package ca.etsmtl.gti785.servlet;

import java.io.IOException;
import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import ca.etsmtl.gti785.util.Constants;
import ca.etsmtl.gti785.util.ServerObserver;

/**
 * This servlet ("/server/notifications") is used for the long polling notifications between the server and the client side. The GET pauses the request and waits for a notification. 
 * When received, returns a 200 OK. If the server has no notifications after a while, it returns a 408 REQUEST_TIMEOUT.
 * @author Étienne Faucher
 */
@WebServlet(urlPatterns="/server/notifications", asyncSupported=true)
public class LongPolling extends HttpServlet 
{
	private static final long serialVersionUID = 1L;
      
    public LongPolling() 
    {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
	{
		AsyncContext asyncContext = request.startAsync();
		asyncContext.setTimeout(Constants.Timeout_delay);
		
		asyncContext.addListener(new AsyncListener() 
		{
			@Override
			public void onTimeout(AsyncEvent event) throws IOException 
			{
				AsyncContext context = event.getAsyncContext();
				
				if(ServerObserver.getInstanceOf().DeleteAsyncContext(context))
				{
					HttpServletResponse response = (HttpServletResponse) context.getResponse();
					response.setStatus(HttpServletResponse.SC_REQUEST_TIMEOUT);
					context.complete();
				}
			}
			
			@Override
			public void onStartAsync(AsyncEvent arg0) throws IOException 
			{				
			}
			
			@Override
			public void onError(AsyncEvent arg0) throws IOException 
			{				
			}
			
			@Override
			public void onComplete(AsyncEvent arg0) throws IOException 
			{				
			}
		});
		
		ServerObserver.getInstanceOf().AddAsyncContext(asyncContext);
	}
}
